package controller;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import core.*;
import model.*;

public class CheckAnswer extends HttpServlet{
	private static final long serialVersionUID = 1L;
	private static PgSQL db = PgSQL.getInstance();
	
	public void doPost(HttpServletRequest request, HttpServletResponse response){
		CurrentUser user = new CurrentUser(request);
		if(!user.getGroup().hasPermission(UserGroup.ANSWER_QUESTION)){
			View.showMessage(request, response, "Sorry, but you have no permission to answer questions.", "back");
			return;
		}
		
		//Analyze User Answers
		Map<Integer, String> question_answers = new LinkedHashMap<Integer, String>();
		Enumeration<String> vars = request.getParameterNames();
		while(vars.hasMoreElements()){
			String var = vars.nextElement();
			if(!var.startsWith("id_")){
				continue;
			}
			
			int qid = 0;
			if(var.indexOf("[") < 0){
				qid = Integer.parseInt(var.substring(3));
				String value = request.getParameter(var);
				if(qid <= 0){
					continue;
				}
				question_answers.put(qid, value);
			
			}else{
				String[] tmp = var.substring(3).split("\\[");
				qid = Integer.parseInt(tmp[0]);
				String answer = tmp[1].substring(0, tmp[1].indexOf("]"));
				if(!question_answers.containsKey(qid)){
					question_answers.put(qid, answer);
				}else{
					question_answers.put(qid, question_answers.get(qid).concat(answer));
				}
			}
		}

		if(question_answers.isEmpty()){
			View.showMessage(request, response, "You have done no questions.", "back");
			return;
		}
		
		//查询数据库比对结果计算得分
		int pid = Tool.intval(request.getParameter("pid"));
		
		if(pid > 0){
			int timeout = -1;
			ResultSet rs = db.query("SELECT timeout FROM qz_paper WHERE pid=" + pid);
			try{
				if(rs != null && rs.next()){
					timeout = rs.getInt(1);
				}else{
					pid = -1;
				}
			}catch(SQLException e){
				e.printStackTrace();
			}
			
			if(timeout > 0){
				long start_time = Long.parseLong(request.getSession().getAttribute("paper_start_time_" + pid).toString());
				long current_time = System.currentTimeMillis() / 1000;
				if(current_time - start_time - timeout > Config.acceptablePaperSubmitDelay){
					View.showMessage(request, response, "Sorry, you missed the deadline.", "back");
					return;
				}
			}
		}
		
		int score = 0;
		LinkedList<ChoiceQuestion> question_list = new LinkedList<ChoiceQuestion>();

		if(pid <= 0){
			String condition = Tool.implode(",", question_answers.keySet().toArray());
			ResultSet rs = db.query("SELECT * FROM qz_choicequestion WHERE qid IN (" + condition + ")");
			try{
				while(rs.next()){
					question_list.add(ChoiceQuestion.fromDatabase(rs));
				}
			}catch(SQLException e){
				e.printStackTrace();
			}
		}else{
			LinkedList<Boolean> question_result = new LinkedList<Boolean>();
			
			ResultSet rs = db.query("SELECT q.*,p.point FROM qz_papercontent p LEFT JOIN qz_choicequestion q ON q.qid=p.qid WHERE p.pid=" + pid);
			try{
				while(rs.next()){
					ChoiceQuestion q = ChoiceQuestion.fromDatabase(rs);
					question_list.add(q);
					
					if(checkAnswer(q, question_answers.get(q.getQid()))){
						score += rs.getInt(6);
						question_result.add(true);
					}else{
						question_result.add(false);
					}
				}
			}catch(SQLException e){
				e.printStackTrace();
			}
			
			if(user.isLoggedIn()){
				db.update("INSERT INTO qz_paperlog(pid, uid, score, dateline) VALUES (" + pid + ", " + user.getUid() + ", " + score + ", extract(epoch FROM now()))");
			}
			
			request.setAttribute("score", score);
			request.setAttribute("question_result[]", question_result.toArray(new Boolean[0]));
		}
		
		request.setAttribute("question_list[]", question_list.toArray(new ChoiceQuestion[0]));
		
		if(request.getParameter("ajax") != null){
			View.show(request, response, "show_answer_ajax");
		}else{
			View.show(request, response, "show_answer");
		}
	}
	
	public void doGet(HttpServletRequest request, HttpServletResponse response){
		try {
			response.sendRedirect("QuestionList");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public boolean checkAnswer(Question q, String answer){
		if(answer == null || q.getAnswer().length() != answer.length()){
			return false;
		}
		
		if(answer.matches("[0-9]+")){
			for(int i = 0; i < answer.length(); i++){
				int ch = answer.charAt(i) - '0' + 'A';
				if(q.getAnswer().indexOf(ch) < 0){
					return false;
				}
			}
		}else{
			for(int i = 0; i < answer.length(); i++){
				int ch = answer.charAt(i);
				if(q.getAnswer().indexOf(ch) < 0){
					return false;
				}
			}
		}
		
		return true;
	}
}
